﻿//------------------------------------------------------------------------------
// Copyright © FRA & FV 2014
// All rights reserved
//------------------------------------------------------------------------------
// Binary Serialization Custom Tool
//
// SVN revision information:
//   $Revision: 97 $
//------------------------------------------------------------------------------
using System.CodeDom;
using FRAFV.Binary.Serialization.CodeDom;

namespace FRAFV.Binary.Serialization
{
	/// <summary>
	/// public IEnumerable&lt;TItem&gt; Items
	/// {
	/// 	get
	/// 	{
	/// 		if (Property1 != null)
	/// 			yield return Property1;
	/// 		...
	/// 		
	/// 		foreach (var item in Property2)
	/// 			yield return item;
	/// 		...
	/// 	}
	/// }
	/// </summary>
	internal sealed class EnumerableGenerator : ClassGenerator.MethodGenerator
	{
		public EnumerableGenerator(ClassParser cls)
			: base(cls) { }

		protected override ClassGenerator.MethodContext CreateMember(ClassParser cls)
		{
			//IEnumerable<TItem> Items
			var code = new CodeMemberProperty
			{
				Attributes = MemberAttributes.Public | MemberAttributes.Final,
				Name = "Items",
				HasGet = true,
				Type = new CodeTypeReference("System.Collections.Generic.IEnumerable", cls.IEnumerableType.AsType())
			};
			//[System.Xml.Serialization.XmlIgnoreAttribute()]
			code.CustomAttributes.Add(new CodeAttributeDeclaration("System.Xml.Serialization.XmlIgnoreAttribute".AsType()));
			return new MethodContext(cls, code);
		}

		protected override void Init() { }

		protected override ClassGenerator.PropertyGenerator CreateProperty(ClassParser.ClassProperty prop)
		{
			var context = new ClassGenerator.PropertyContext(this.context, prop);
			return new PropertyItemGenerator(context, CreateItemArray(context));
		}

		private ClassGenerator.PropertyGenerator CreateItemArray(ClassGenerator.PropertyContext context)
		{
			return null;
		}

		private sealed class MethodContext : ClassGenerator.MethodContext
		{
			public MethodContext(ClassParser cls, CodeMemberProperty member)
				: base(cls, member, member.GetStatements) { }
		}

		private sealed class PropertyItemGenerator : ClassGenerator.PropertyItemGenerator
		{
			public PropertyItemGenerator(ClassGenerator.PropertyContext context, ClassGenerator.PropertyGenerator array)
				: base(context, array) { }

			protected override CodeStatementCollection GenerateData()
			{
				if (context.IsRepeatItem)
				{
					//foreach(var item in Property) {
					Statements.ForEach(context.Property, "item").Statements
						.Comment(Name)
						//yield return item;
						.YieldReturn("item".AsVariable());
				}
				else
				{
					//if (Property != null) {
					Statements.Condition(PropertyIsNotNull).TrueStatements
						.Comment(Name)
						//yield return Property;
						.YieldReturn(Name.AsField());
				}
				return null;
			}
		}
	}
}
